﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Plumbing;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LayDuctTerminal : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Transaction transaction2 = null;
			Transaction transaction3 = null;
			ElementId elementId = null;
			ListItemPlane listItemPlane = null;
			Document document = null;
			if (commandData == null)
			{
				throw new System.ArgumentNullException();
			}
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			ElementSet elementSet = null;
			RectLayParamers rectLayParamers = null;
			if (!YJKRevitTools.ViewCheck(activeUIDocument, new List<ViewType>
			{
				1,
				2
			}))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Result result;
			try
			{
				HYEquipmentCommon hyequipmentCommon = new HYEquipmentCommon();
				ICollection<ElementId> allFamilyInstance = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_DuctTerminal);
				ICollection<Element> collectionId = null;
				ILayForm layForm = new ILayForm(document);
				FamilySymbol familySymbol = layForm.LayAirTerminalFormShow(commandData, "风口");
				LayAreaParameter layAreaParas = layForm.layAreaParas;
				AirTerminalParamNew airTerminalParaNew = layForm.airTerminalParaNew;
				LayLineParameter layLineParas = layForm.layLineParas;
				LayMidParameter layMidParas = layForm.layMidParas;
				LayAutoParameter layAutoParas = layForm.layAutoParas;
				int layTerminalType = layForm.layTerminalType;
				listItemPlane = layForm.planeParam;
				rectLayParamers = layForm.rectLayParas;
				bool flag = false;
				if (familySymbol == null)
				{
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					SideTerminalConnDuct sideTerminalConnDuct = new SideTerminalConnDuct(activeUIDocument, layForm, familySymbol);
					bool flag2 = true;
					if (layForm.BeSideLay)
					{
						flag2 = false;
					}
					ConnectHelper connectHelper = new ConnectHelper();
					if (layTerminalType == 0 && flag2)
					{
						flag = true;
						try
						{
							activeUIDocument.PromptForFamilyInstancePlacement(familySymbol);
							goto IL_A9D;
						}
						catch (Exception)
						{
							goto IL_A9D;
						}
					}
					transaction = new Transaction(document, "风口布置");
					transaction.Start();
					for (;;)
					{
						LayDuctTerminalRectDrawJin layDuctTerminalRectDrawJin = null;
						SubTransaction subTransaction = null;
						try
						{
							try
							{
								subTransaction = new SubTransaction(document);
								subTransaction.Start();
								if (!flag2 && layTerminalType == 0)
								{
									if (layForm.BeSideLay)
									{
										sideTerminalConnDuct.ConnSingleSideTerminal();
									}
									else
									{
										XYZ xyz = selection.PickPoint("选择一个点");
										Reference reference = UnifiedModified.GetReference(document.GetElementById(elementId) as ReferencePlane);
										elementSet = connectHelper.LayFamilyInstance(xyz, reference, familySymbol, document);
									}
								}
								else if (layTerminalType == 3)
								{
									if (rectLayParamers == null)
									{
										MessageBox.Show("布置失败，区域布置参数为空", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
										break;
									}
									LayDuctTerminalRectDrawJin layDuctTerminalRectDrawJin2;
									layDuctTerminalRectDrawJin = (layDuctTerminalRectDrawJin2 = new LayDuctTerminalRectDrawJin(activeUIDocument, rectLayParamers));
									try
									{
										rectLayParamers.PointBase = selection.PickPoint("选择第一个点，此点为矩形的基点：");
										layDuctTerminalRectDrawJin.StartPoint = rectLayParamers.PointBase;
										rectLayParamers.PointDiagonal = selection.PickPoint("选择第二个点，此点位矩形的对角点：");
										layDuctTerminalRectDrawJin.Dispose();
									}
									finally
									{
										if (layDuctTerminalRectDrawJin2 != null)
										{
											((IDisposable)layDuctTerminalRectDrawJin2).Dispose();
										}
									}
									List<List<XYZ>> pointSet = new RectLayPoint(rectLayParamers).PointSet;
									if (pointSet != null && pointSet.Count > 0)
									{
										elementSet = new ElementSet();
										foreach (List<XYZ> xyzList in pointSet)
										{
											ElementSet elementSet2;
											if (!flag2)
											{
												Reference reference = UnifiedModified.GetReference(document.GetElementById(elementId) as ReferencePlane);
												elementSet2 = connectHelper.LayFamilyInstance(xyzList, reference, familySymbol, document);
											}
											else
											{
												elementSet2 = connectHelper.LayFamilyInstance(xyzList, familySymbol, document.ActiveView.GenLevel, 0, document);
											}
											foreach (object obj in elementSet2)
											{
												Element element = (Element)obj;
												elementSet.Insert(element);
											}
											document.Regenerate();
										}
										YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
										IEnumerator enumerator2 = elementSet.GetEnumerator();
										{
											while (enumerator2.MoveNext())
											{
												object obj2 = enumerator2.Current;
												hyrotateFamilyInstance.RotateElem(document, obj2 as FamilyInstance, rectLayParamers.AngleRow);
											}
											goto IL_A35;
										}
									}
									MessageBox.Show("选取的区域太小，布置失败！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
								}
								else if (layTerminalType == 4)
								{
									if (layMidParas != null)
									{
										LayDuctTerminalDrawUtility.airTerminalPara = airTerminalParaNew;
										XYZ xyz2;
										XYZ max;
										using (LayDuctTerminalCenterDrawJin layDuctTerminalCenterDrawJin = new LayDuctTerminalCenterDrawJin(activeUIDocument, layMidParas))
										{
											xyz2 = selection.PickPoint("选择起始点坐标，此点为矩形的一个对角点");
											layDuctTerminalCenterDrawJin.StartPoint = xyz2;
											max = selection.PickPoint("选择终止点坐标，此点为矩形的另一个对角点");
											layDuctTerminalCenterDrawJin.Dispose();
										}
										List<XYZ> list = new List<XYZ>();
										if (layMidParas.Type == 0)
										{
											list = connectHelper.CalculateLayFamilyInstanceXYZ(xyz2, max, layMidParas.RowCount, layMidParas.ColCount, layMidParas.LeftDistance, layMidParas.RightDistance, layMidParas.TopDistance, layMidParas.BottomDistance, UnitConvert.CovertToAPI(airTerminalParaNew.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
										}
										else
										{
											list = connectHelper.CalculateLayFamilyInstanceXYZ(xyz2, max, layMidParas.RowDistance, layMidParas.ColDistance, UnitConvert.CovertToAPI(airTerminalParaNew.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
										}
										if (list != null && list.Count > 0)
										{
											if (!flag2)
											{
												Reference reference = UnifiedModified.GetReference(document.GetElementById(elementId) as ReferencePlane);
												elementSet = connectHelper.LayFamilyInstance(list, reference, familySymbol, document);
											}
											else
											{
												elementSet = connectHelper.LayFamilyInstance(list, familySymbol, document.ActiveView.GenLevel, 0, document);
											}
										}
										else
										{
											MessageBox.Show("布置失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
										}
									}
									else
									{
										MessageBox.Show("布置失败，居中布置参数为空", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
									}
								}
								else if (layTerminalType == 1)
								{
									if (layLineParas != null)
									{
										ISelectionFilter selectionFilter = new LineAndDuctSelectionFilter();
										Reference reference2 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择一条直线或者风管");
										Element element2 = document.GetElement(reference2);
										XYZ globalPoint = reference2.GlobalPoint;
										if (element2.Location is LocationCurve)
										{
											Curve curve;
											if (element2 is Duct)
											{
												YJKPiping<Duct> hypiping = new YJKPiping<Duct>(element2 as Duct);
												XYZ xyz3 = new XYZ(hypiping.StartConnector.Origin.X, hypiping.StartConnector.Origin.Y, hypiping.StartConnector.Origin.Z - hypiping.GetHeightOrDiameter() / 2.0);
												XYZ xyz4 = new XYZ(hypiping.EndConnector.Origin.X, hypiping.EndConnector.Origin.Y, hypiping.EndConnector.Origin.Z - hypiping.GetHeightOrDiameter() / 2.0);
												curve = Line.CreateBound(xyz3, xyz4);
											}
											else
											{
												curve = (element2.Location as LocationCurve).Curve;
											}
											if (curve is Line)
											{
												YJKLine hyline = new YJKLine(curve as Line);
												List<XYZ> list2 = new List<XYZ>();
												if (layLineParas.LimitFlag == 1)
												{
													list2 = hyline.GetLayLineXYZList(globalPoint, layLineParas.Count, layLineParas.Ratio, UnitConvert.CovertToAPI(airTerminalParaNew.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
												}
												else
												{
													list2 = hyline.GetLayLineXYZList(globalPoint, UnitConvert.LengthToStd(layLineParas.Distance / 1000.0), UnitConvert.LengthToStd(layLineParas.DistanceSide / 1000.0), UnitConvert.CovertToAPI(airTerminalParaNew.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
												}
												if (list2 != null && list2.Count > 0)
												{
													if (!flag2)
													{
														Reference reference = UnifiedModified.GetReference(document.GetElementById(elementId) as ReferencePlane);
														elementSet = connectHelper.LayFamilyInstance(list2, reference, familySymbol, document);
													}
													else
													{
														elementSet = connectHelper.LayFamilyInstance(list2, familySymbol, document.ActiveView.GenLevel, 0, document);
													}
												}
												else
												{
													MessageBox.Show("布置失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
												}
											}
											else
											{
												MessageBox.Show("布置失败，请选择一条直线", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
											}
										}
									}
									else
									{
										MessageBox.Show("布置失败，沿线布置参数为空", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
									}
								}
								else if (layTerminalType == 2)
								{
									ISelectionFilter selectionFilter2 = new BoostLineSelectionFilter();
									IList<Element> elemList = selection.PickElementsByRectangle(selectionFilter2, "请框选网格");
									List<XYZ> list3 = new List<XYZ>();
									list3 = sideTerminalConnDuct.GetLayGridXYZList(elemList, UnitConvert.CovertToAPI(airTerminalParaNew.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
									if (list3 != null && list3.Count > 0)
									{
										if (!flag2)
										{
											Reference reference = UnifiedModified.GetReference(document.GetElementById(elementId) as ReferencePlane);
											elementSet = connectHelper.LayFamilyInstance(list3, reference, familySymbol, document);
										}
										else
										{
											elementSet = connectHelper.LayFamilyInstance(list3, familySymbol, document.ActiveView.GenLevel, 0, document);
										}
									}
									else
									{
										MessageBox.Show("布置失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
									}
								}
								else if (layTerminalType == 5)
								{
									if (layForm.BeSideLay)
									{
										sideTerminalConnDuct.ConnAlongLineSideTerminal();
									}
									else
									{
										ISelectionFilter selectionFilter3 = new RoomAndSpaceSelectionFilter();
										Element element3;
										do
										{
											Reference reference3 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter3, "请选择一个房间");
											element3 = document.GetElement(reference3);
											if (!sideTerminalConnDuct.CheckRoom(element3))
											{
												YJKMessageBox.Information("目前仅支持矩形房间或空间，请重新选择!");
											}
										}
										while (!sideTerminalConnDuct.CheckRoom(element3));
										XYZ xyz5 = new XYZ(element3.get_BoundingBox(document.ActiveView).Min.X, element3.get_BoundingBox(document.ActiveView).Min.Y, 0.0);
										XYZ xyz6 = new XYZ(element3.get_BoundingBox(document.ActiveView).Max.X, element3.get_BoundingBox(document.ActiveView).Max.Y, 0.0);
										double num = Math.Abs(xyz6.X - xyz5.X);
										double num2 = Math.Abs(xyz6.Y - xyz5.Y);
										if (num > 0.01 || num2 > 0.01)
										{
											int num3 = (int)Math.Round(Math.Sqrt(num / num2 * (double)layAutoParas.AllCount));
											layAutoParas.RowCount = ((num3 != 0) ? num3 : 1);
											layAutoParas.ColCount = (int)Math.Ceiling((double)layAutoParas.AllCount / (double)num3);
											layAutoParas.Ratio = 0.5;
											List<XYZ> list4 = new List<XYZ>();
											list4 = connectHelper.CalculateLayFamilyInstanceXYZ(xyz5, xyz6, layAutoParas.RowCount, layAutoParas.ColCount, layAutoParas.Ratio, UnitConvert.CovertToAPI(airTerminalParaNew.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
											if (list4 != null && list4.Count > 0)
											{
												elementSet = connectHelper.LayFamilyInstance(list4, familySymbol, document.ActiveView.GenLevel, 0, document);
											}
											else
											{
												YJKMessageBox.Information("布置失败");
											}
										}
										else
										{
											YJKMessageBox.Information("房间边界计算失败");
										}
									}
								}
								IL_A35:
								document.Regenerate();
								collectionId = hyequipmentCommon.GetAllTag(document, BuiltInCategory.OST_DuctTerminalTags);
								if (elementSet != null)
								{
									sideTerminalConnDuct.SettingParameter(document, elementSet, collectionId, airTerminalParaNew, flag2, 1, familySymbol);
								}
								subTransaction.Commit();
							}
							catch (Exception ex)
							{
								if (layDuctTerminalRectDrawJin != null)
								{
									layDuctTerminalRectDrawJin.Dispose();
								}
								throw ex;
							}
							continue;
						}
						finally
						{
							if (subTransaction != null && (int)subTransaction.GetStatus() != 3)
							{
								subTransaction.RollBack();
							}
						}
						break;
					}
					transaction.Commit();
					IL_A9D:
					if (flag)
					{
						bool isSetLevel = false;
						if (listItemPlane == null)
						{
							isSetLevel = true;
						}
						try
						{
							transaction2 = new Transaction(document, "设置单个布置风口参数");
							transaction2.Start();
						}
						catch (Exception)
						{
							return Autodesk.Revit.UI.Result.Failed;
						}
						collectionId = hyequipmentCommon.GetAllTag(document, BuiltInCategory.OST_DuctTerminalTags);
						IEnumerable<ElementId> allFamilyInstance2 = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_DuctTerminal);
						elementSet = new ElementSet();
						foreach (ElementId elementId2 in allFamilyInstance2)
						{
							bool flag3 = false;
							foreach (ElementId elementId3 in allFamilyInstance)
							{
								if (elementId2 == elementId3)
								{
									flag3 = true;
									break;
								}
							}
							if (!flag3)
							{
								elementSet.Insert(document.GetElementById(elementId2));
							}
						}
						sideTerminalConnDuct.SettingParameter(document, elementSet, collectionId, airTerminalParaNew, isSetLevel, 2, familySymbol);
						transaction2.Commit();
					}
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex2)
			{
				message = ex2.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction != null && (int)transaction.GetStatus() == 1 && (int)transaction.GetStatus() != 2)
				{
					transaction.Commit();
				}
				if (transaction2 != null && transaction2.GetStatus() != 3 && transaction2.GetStatus() != 2 && transaction2.GetStatus() != null)
				{
					transaction2.RollBack();
				}
				if (transaction3 != null && transaction3.GetStatus() != 3 && transaction3.GetStatus() != 2)
				{
					transaction3.RollBack();
				}
				if (null != elementId && listItemPlane != null && document != null && (1 == listItemPlane.PlaneType || listItemPlane.PlaneType == 0))
				{
					Transaction transaction4 = new Transaction(document, "删除临时平面");
					transaction4.Start();
					document.Delete(elementId);
					transaction4.Commit();
				}
			}
			return result;
		}
	}
}
